home *** CD-ROM | disk | FTP | other *** search
/ MacAddict 108 / MacAddict108.iso / Software / Internet & Communication / JunkMatcher 1.5.5.dmg / JunkMatcher.app / Contents / Resources / lib / python2.3 / site-packages / rwlock.py < prev   
Encoding:
Python Source  |  2005-06-01  |  3.5 KB  |  126 lines

  1. # This is taken from http://www.majid.info/mylos/weblog/2004/11/04-1.html
  2. # Written by Fazal MAJID, November 4, 2004
  3.  
  4. """Simple reader-writer locks in Python
  5. Many readers can hold the lock XOR one and only one writer"""
  6. import threading
  7.  
  8. version = """$Id: rwlock.py,v 1.1 2004/12/22 22:32:00 majid Exp $"""
  9.  
  10. class RWLock:
  11.   """
  12. A simple reader-writer lock Several readers can hold the lock
  13. simultaneously, XOR one writer. Write locks have priority over reads to
  14. prevent write starvation.
  15. """
  16.   def __init__(self):
  17.     self.rwlock = 0
  18.     self.writers_waiting = 0
  19.     self.monitor = threading.Lock()
  20.     self.readers_ok = threading.Condition(self.monitor)
  21.     self.writers_ok = threading.Condition(self.monitor)
  22.   def acquire_read(self):
  23.     """Acquire a read lock. Several threads can hold this typeof lock.
  24. It is exclusive with write locks."""
  25.     self.monitor.acquire()
  26.     while self.rwlock < 0 or self.writers_waiting:
  27.         self.readers_ok.wait()
  28.     self.rwlock += 1
  29.     self.monitor.release()
  30.   def acquire_write(self):
  31.     """Acquire a write lock. Only one thread can hold this lock, and
  32. only when no read locks are also held."""
  33.     self.monitor.acquire()
  34.     while self.rwlock != 0:
  35.       self.writers_waiting += 1
  36.       self.writers_ok.wait()
  37.       self.writers_waiting -= 1
  38.     self.rwlock = -1
  39.     self.monitor.release()
  40.   def promote(self):
  41.     """Promote an already-acquired read lock to a write lock
  42.     WARNING: it is very easy to deadlock with this method"""
  43.     self.monitor.acquire()
  44.     self.rwlock -= 1
  45.     while self.rwlock != 0:
  46.       self.writers_waiting += 1
  47.       self.writers_ok.wait()
  48.       self.writers_waiting -= 1
  49.     self.rwlock = -1
  50.     self.monitor.release()
  51.   def demote(self):
  52.     """Demote an already-acquired write lock to a read lock"""
  53.     self.monitor.acquire()
  54.     self.rwlock = 1
  55.     self.readers_ok.notifyAll()
  56.     self.monitor.release()
  57.   def release(self):
  58.     """Release a lock, whether read or write."""
  59.     self.monitor.acquire()
  60.     if self.rwlock < 0:
  61.       self.rwlock = 0
  62.     else:
  63.       self.rwlock -= 1
  64.     wake_writers = self.writers_waiting and self.rwlock == 0
  65.     wake_readers = self.writers_waiting == 0
  66.     self.monitor.release()
  67.     if wake_writers:
  68.       self.writers_ok.acquire()
  69.       self.writers_ok.notify()
  70.       self.writers_ok.release()
  71.     elif wake_readers:
  72.       self.readers_ok.acquire()
  73.       self.readers_ok.notifyAll()
  74.       self.readers_ok.release()
  75.  
  76. if __name__ == '__main__':
  77.   import time
  78.   rwl = RWLock()
  79.   class Reader(threading.Thread):
  80.     def run(self):
  81.       print self, 'start'
  82.       rwl.acquire_read()
  83.       print self, 'acquired'
  84.       time.sleep(5)    
  85.       print self, 'stop'
  86.       rwl.release()
  87.   class Writer(threading.Thread):
  88.     def run(self):
  89.       print self, 'start'
  90.       rwl.acquire_write()
  91.       print self, 'acquired'
  92.       time.sleep(10)    
  93.       print self, 'stop'
  94.       rwl.release()
  95.   class ReaderWriter(threading.Thread):
  96.     def run(self):
  97.       print self, 'start'
  98.       rwl.acquire_read()
  99.       print self, 'acquired'
  100.       time.sleep(5)    
  101.       rwl.promote()
  102.       print self, 'promoted'
  103.       time.sleep(5)    
  104.       print self, 'stop'
  105.       rwl.release()
  106.   class WriterReader(threading.Thread):
  107.     def run(self):
  108.       print self, 'start'
  109.       rwl.acquire_write()
  110.       print self, 'acquired'
  111.       time.sleep(10)    
  112.       print self, 'demoted'
  113.       rwl.demote()
  114.       time.sleep(10)    
  115.       print self, 'stop'
  116.       rwl.release()
  117.   Reader().start()
  118.   time.sleep(1)
  119.   Reader().start()
  120.   time.sleep(1)
  121.   ReaderWriter().start()
  122.   time.sleep(1)
  123.   WriterReader().start()
  124.   time.sleep(1)
  125.   Reader().start()
  126.